import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const TestTopicCardView(),
    );
  }
}

class TestTopicCardView extends StatefulWidget {
  const TestTopicCardView({super.key});

  @override
  State<TestTopicCardView> createState() => _TestTopicCardViewState();
}

class _TestTopicCardViewState extends State<TestTopicCardView>
    with TickerProviderStateMixin {
  List<TopicType> topicTypeList = [];
  late TabController _tabController;
  late TopicType currentTopicType;
  double tabBarHeight = 30;
  @override
  void initState() {
    _initData();
    super.initState();
  }

  void _initData() {
    topicTypeList = [
      TopicType(
        topicTitle: 'Vocabulary',
        items: [
          TopicTypeCard(),
        ],
      ),
      TopicType(
        topicTitle: 'Sentence',
        items: [
          TopicTypeCard(),
        ],
      ),
      TopicType(
        topicTitle: 'Writing',
        items: [
          TopicTypeCard(),
        ],
      ),
    ];
    currentTopicType = topicTypeList.last;
    _updateTabController();
  }

  void _onAddTopic() {
    setState(() {
      topicTypeList.add(TopicType(
        items: [
          TopicTypeCard(),
        ],
      ));
      _updateTabController();
    });
  }

  void _onDeleteTopic(int index) {
    setState(() {
      topicTypeList.removeAt(index);
      _updateTabController();
    });
  }

  void _updateTabController() {
    _tabController = TabController(length: topicTypeList.length, vsync: this);
    _tabController.addListener(() {
      setState(() {
        currentTopicType = topicTypeList[_tabController.index];
      });
    });
    if (topicTypeList.isNotEmpty) {
      _tabController.index = topicTypeList.length - 1;
    }
  }

  void _onChangeCurrentTopic(int index) {
    _tabController.animateTo(index);
  }

  void _onAddTopicCard() {
    setState(() {
      currentTopicType.items?.add(TopicTypeCard());
    });
  }

  void _onDeleteTopicCard(int index) {
    setState(() {
      currentTopicType.items?.removeAt(index);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        //当前页面是根页面时，AppBar的默认图标会自动隐藏。
        //这里为了和UI统一，所以显示一个占位图标
        leading: GestureDetector(
          //不做点击处理
          onTap: () {},
          child: Icon(Icons.arrow_back),
        ),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _buildTopBarPart(),
          Expanded(
            child: TabBarView(
              controller: _tabController,
              children: List.generate(
                topicTypeList.length,
                (index) => _buildTabViewPart(index),
              ),
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _onAddTopicCard,
        backgroundColor: Colors.blue,
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }

  Widget _buildTopBarPart() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 20),
            alignment: Alignment.centerLeft,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      constraints: BoxConstraints(
                        minWidth: topicTypeList.isEmpty ? 0 : 160,
                      ),
                      child: Stack(
                        children: [
                          Positioned(
                            left: 0,
                            right: 0,
                            child: _buildTabBarBg(),
                          ),
                          Row(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              ...List.generate(topicTypeList.length, (index) {
                                final currentIndex = topicTypeList.indexWhere(
                                    (element) => element == currentTopicType);
                                return Row(
                                  children: [
                                    GestureDetector(
                                      onTap: () => _onChangeCurrentTopic(index),
                                      child: Container(
                                        width: 140,
                                        height: tabBarHeight,
                                        padding: EdgeInsets.only(
                                            left: 10, right: 10),
                                        child: IntrinsicHeight(
                                          child: Row(
                                            mainAxisAlignment:
                                                MainAxisAlignment.spaceBetween,
                                            crossAxisAlignment:
                                                CrossAxisAlignment.center,
                                            mainAxisSize: MainAxisSize.max,
                                            children: [
                                              Expanded(
                                                child: Text(
                                                  topicTypeList[index]
                                                      .topicTitle,
                                                  style: TextStyle(
                                                    fontSize: 16,
                                                    fontWeight: FontWeight.w400,
                                                  ),
                                                  maxLines: 1,
                                                  textAlign: TextAlign.start,
                                                  overflow:
                                                      TextOverflow.ellipsis,
                                                ),
                                              ),
                                              _buildTopBarEndIc(
                                                icon: Icons.close,
                                                onTap: () =>
                                                    _onDeleteTopic(index),
                                              ),
                                            ],
                                          ),
                                        ),
                                      ),
                                    ),
                                    if (currentIndex != -1 &&
                                        (index != currentIndex &&
                                            index != currentIndex - 1 &&
                                            index != topicTypeList.length - 1))
                                      Container(
                                        width: 1,
                                        height: 20,
                                        margin: EdgeInsets.only(
                                          top: 4,
                                          bottom: 4,
                                        ),
                                        color: currentTopicType ==
                                                topicTypeList[index]
                                            ? Colors.transparent
                                            : Colors.grey
                                                .withValues(alpha: 0.5),
                                      ),
                                  ],
                                );
                              }),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
                _buildTopBarEndIc(
                  icon: Icons.add,
                  onTap: _onAddTopic,
                ),
                SizedBox(width: 150),
              ],
            ),
          ),
        ),
        Container(
          height: 2,
          color: Colors.blue,
        )
      ],
    );
  }

  Widget _buildTabBarBg() {
    if (topicTypeList.isEmpty) {
      return SizedBox.shrink();
    }
    return LayoutBuilder(
      builder: (context, constraints) {
        double tabWidth = constraints.maxWidth / topicTypeList.length;
        double maxWidth = constraints.maxWidth;
        if (topicTypeList.length == 1) {
          tabWidth = 140;
          maxWidth = tabWidth + 20;
        }
        return Container(
          height: tabBarHeight,
          width: maxWidth,
          decoration: BoxDecoration(
            color: Colors.transparent,
          ),
          child: AnimatedBuilder(
            animation: _tabController.animation!,
            builder: (context, child) => Transform.translate(
              offset: Offset(
                _tabController.animation!.value * tabWidth - 10,
                0,
              ),
              child: child,
            ),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                SizedBox(
                  height: 10,
                  width: 10,
                  child: CustomPaint(
                    painter: BezierCurvePainter(isLeft: true),
                  ),
                ),
                Container(
                  height: tabBarHeight,
                  width: tabWidth,
                  alignment: Alignment.centerLeft,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.only(
                      topRight: Radius.circular(6),
                      topLeft: Radius.circular(6),
                    ),
                    color: Colors.blue,
                  ),
                ),
                SizedBox(
                  height: 10,
                  width: 10,
                  child: CustomPaint(
                    painter: BezierCurvePainter(isLeft: false),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Widget _buildTopBarEndIc(
      {required IconData icon, required VoidCallback onTap}) {
    return GestureDetector(
      onTap: onTap,
      behavior: HitTestBehavior.opaque,
      child: Icon(icon),
    );
  }

  Widget _buildTabViewPart(int index) {
    if (topicTypeList[index].items?.isNotEmpty != true) {
      return SizedBox.shrink();
    }
    final items = topicTypeList[index].items!;
    return ListView.builder(
      key: ValueKey(index),
      itemCount: items.length,
      shrinkWrap: true,
      itemBuilder: (context, index) {
        return Container(
          key: ValueKey(items[index].id),
          padding: EdgeInsets.all(8),
          margin: EdgeInsets.only(left: 16, right: 16, top: 8),
          decoration: BoxDecoration(
            border: Border.all(
              width: 1,
              color: Colors.blue,
            ),
            borderRadius: BorderRadius.circular(10),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text(
                    (index + 1).toString(),
                    style: TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w400,
                    ),
                  ),
                  GestureDetector(
                    onTap: () => _onDeleteTopicCard(index),
                    behavior: HitTestBehavior.opaque,
                    child: Padding(
                      padding: const EdgeInsets.all(2.0),
                      child: Icon(Icons.delete_outline),
                    ),
                  ),
                ],
              ),
              Divider(
                height: 1,
                color: Colors.grey.withValues(alpha: 0.3),
              ),
              SizedBox(height: 8),
              RichText(
                text: TextSpan(
                  children: [
                    TextSpan(
                      text: "Writing Topic",
                      style: TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.w600,
                          color: Colors.black),
                    ),
                    TextSpan(
                      text: "*",
                      style: TextStyle(
                        color: Colors.red,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ],
                ),
              ),
              TextField(
                controller:
                    TextEditingController(text: items[index].topicContent),
                maxLength: 1000,
                maxLines: 1,
                keyboardType: TextInputType.text,
                textInputAction: TextInputAction.done,
                textAlignVertical: TextAlignVertical.center,
                decoration: InputDecoration(
                  hintText: items[index].topicHint,
                  hintStyle: TextStyle(
                    fontSize: 14,
                    color: Colors.grey.withValues(alpha: 0.8),
                  ),
                  counterText: "",
                  isCollapsed: true,
                  contentPadding: EdgeInsets.zero,
                  border:
                      const UnderlineInputBorder(borderSide: BorderSide.none),
                  enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(
                      color: Colors.grey.withValues(alpha: 0.5),
                    ),
                  ),
                  focusedBorder: UnderlineInputBorder(
                    borderSide: BorderSide(
                      color: Colors.grey.withValues(alpha: 0.5),
                    ),
                  ),
                ),
                onChanged: (value) {
                  items[index].topicContent = value;
                },
              ),
              SizedBox(height: 8),
            ],
          ),
        );
      },
    );
  }
}

class TopicType {
  String topicTitle;
  List<TopicTypeCard>? items;
  TopicType({this.topicTitle = 'Reading', this.items});
}

class TopicTypeCard {
  int id = DateTime.now().millisecondsSinceEpoch;
  String? topicContent;
  String topicHint;
  TopicTypeCard({
    this.topicHint = 'The writing topic has not been filled in',
    this.topicContent,
  });
}

class BezierCurvePainter extends CustomPainter {
  bool isLeft = true;
  BezierCurvePainter({this.isLeft = true});
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    final path = Path();
    if (isLeft) {
      path.moveTo(0, size.height);
      path.quadraticBezierTo(
        size.width,
        size.height,
        size.width,
        0,
      );
      path.lineTo(size.width, size.height);
      path.lineTo(0, size.height);
    } else {
      path.moveTo(size.width, size.height);
      path.quadraticBezierTo(
        0,
        size.height,
        0,
        0,
      );
      path.lineTo(0, size.height);
      path.lineTo(size.width, size.height);
    }
    path.close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
